package com.backend.system.service.impl;

import cn.hutool.core.lang.tree.Tree;
import com.backend.system.beans.menu.ListMenuByRoleReq;
import com.backend.system.beans.menu.ListMenuByRoleVO;
import com.backend.system.dao.entity.Menu;
import com.backend.system.dao.entity.MenuRole;
import com.backend.system.dao.mapper.MenuMapper;
import com.backend.system.service.IMenuRoleService;
import com.backend.system.service.IMenuService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 * 菜单表 服务实现类
 * </p>
 *
 * @author backend-manage
 * @since 2024-04-02
 */
@Service
public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements IMenuService {

    @Resource
    private IMenuRoleService menuRoleService;


    /**
     * 获取所有菜单，树形展示
     *
     * @return 菜单信息
     */
    @Override
    public List<Tree<String>> getAllMenus() {
        return menuToTree(this.list());
    }

    /**
     * 通过角色ID获取角色拥有的菜单列表
     *
     * @param roleId 角色ID
     * @return 菜单列表
     */
    @Override
    public List<Menu> getMenusByRoleId(Long roleId) {
        List<MenuRole> menuRoles = menuRoleService.getMenuRolesByRoleId(roleId);
        if (CollectionUtils.isEmpty(menuRoles)) {
            return Collections.emptyList();
        }

        List<Long> menuIds = menuRoles.stream().map(MenuRole::getMenuId).distinct().toList();

        LambdaQueryWrapper<Menu> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(Menu::getId, menuIds);
        queryWrapper.eq(Menu::getEnabled, 1);
        return this.listByIds(menuIds);
    }

    /**
     * 通过角色ID获取所有菜单列表
     *
     * @param roleId 角色ID
     * @return 菜单列表
     */
    @Override
    public List<Menu> getAllMenusByRoleId(Long roleId) {
        // 查角色已拥有的菜单
        List<MenuRole> menuRoles = menuRoleService.getMenuRolesByRoleId(roleId);
        Set<Long> menuIds = menuRoles.stream().map(MenuRole::getMenuId).collect(Collectors.toSet());

        // 查全部未禁用的菜单
        LambdaQueryWrapper<Menu> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Menu::getEnabled, 1);
        List<Menu> menuList = this.list(queryWrapper);

        // 标记已经拥有的菜单
        for (Menu menu : menuList) {
            menu.setSelected(menuIds.contains(menu.getId()));
        }
        return menuList;
    }

    /**
     * 按角色查询全部未禁用菜单（标识已拥有、未拥有）
     *
     * @param req 请求入参
     * @return 菜单信息
     */
    @Override
    public ListMenuByRoleVO listMenuByRole(ListMenuByRoleReq req) {
        ListMenuByRoleVO vo = new ListMenuByRoleVO();
        // 菜单结构转为树形
        vo.setMenuTree(this.menuToTree(this.getAllMenusByRoleId(req.getRoleId())));
        return vo;
    }
}
